
#include "graphics_functions.h"

using namespace WtfGraphics;

void WtfGraphics::SetColour(const fVector4D& vColour) {
	glColor4fv(vColour.toArray());
};

void WtfGraphics::EnableBlending() {
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
};

void WtfGraphics::DisableBlending() {
	glDisable(GL_BLEND);
};

void WtfGraphics::EnableWireframe(tScalar f) {
	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
};

void WtfGraphics::DisableWireframe() {
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
};


void WtfGraphics::SaveView() {
	glPushMatrix();
};

void WtfGraphics::RestoreView() {
	glPopMatrix();
};

void WtfGraphics::Rotate(const Orientation3D& ori) {
	GLfloat m[16];
	ori.getOpenGLMatrix(m);
	glMultMatrixf(m);
};

void WtfGraphics::Translate(const tVector& v) {
	glTranslated(v[0], v[1], v[2]);
};

void WtfGraphics::Transform(const Transformation3D& t) {
	GLfloat m[16];
	t.getOpenGLMatrix(m);
	glMultMatrixf(m);
};

void WtfGraphics::DrawTriangle(const tVector& a, const tVector& b, const tVector& c) {
	glBegin(GL_TRIANGLES);
	glVertex3d(a[0], a[1], a[2]);
	glVertex3d(b[0], b[1], b[2]);
	glVertex3d(c[0], c[1], c[2]);
	glEnd();
};

void WtfGraphics::DrawQuad(const tVector& a, const tVector& b, const tVector& c, const tVector& d)
{
	glBegin(GL_QUADS);
	glVertex3d(a[0], a[1], a[2]);
	glVertex3d(b[0], b[1], b[2]);
	glVertex3d(c[0], c[1], c[2]);
	glVertex3d(d[0], d[1], d[2]);
	glEnd();
};

void WtfGraphics::DrawBox(const tVector& min, const tVector& max)
{
	glBegin(GL_QUADS);

	glVertex3d(min[0], min[1], min[2]);
	glVertex3d(max[0], min[1], min[2]);
	glVertex3d(max[0], max[1], min[2]);
	glVertex3d(min[0], max[1], min[2]);
	
	glVertex3d(min[0], min[1], max[2]);
	glVertex3d(max[0], min[1], max[2]);
	glVertex3d(max[0], max[1], max[2]);
	glVertex3d(min[0], max[1], max[2]);

	glVertex3d(min[0], min[1], min[2]);
	glVertex3d(max[0], min[1], min[2]);
	glVertex3d(max[0], min[1], max[2]);
	glVertex3d(min[0], min[1], max[2]);

	glVertex3d(min[0], max[1], min[2]);
	glVertex3d(max[0], max[1], min[2]);
	glVertex3d(max[0], max[1], max[2]);
	glVertex3d(min[0], max[1], max[2]);

	glVertex3d(min[0], min[1], min[2]);
	glVertex3d(min[0], min[1], max[2]);
	glVertex3d(min[0], max[1], max[2]);
	glVertex3d(min[0], max[1], min[2]);

	glVertex3d(max[0], min[1], min[2]);
	glVertex3d(max[0], min[1], max[2]);
	glVertex3d(max[0], max[1], max[2]);
	glVertex3d(max[0], max[1], min[2]);

	glEnd();
};



void WtfGraphics::Translate2D(const iVector2D& v) {
	glTranslatef(v[0], v[1], 0.0);
};

void WtfGraphics::Draw2DQuad(const iVector2D& a, const iVector2D& b, const iVector2D& c, const iVector2D& d) {
	glBegin(GL_QUADS);

	glVertex2i(a[0], a[1]);
	glVertex2i(b[0], b[1]);
	glVertex2i(c[0], c[1]);
	glVertex2i(d[0], d[1]);

	glEnd();
};

void WtfGraphics::Draw2DBox(const iVector2D& min, const iVector2D& max) {
	glBegin(GL_QUADS);

	glVertex2i(min[0], min[1]);
	glVertex2i(min[0], max[1]);
	glVertex2i(max[0], max[1]);
	glVertex2i(max[0], min[1]);

	glEnd();
};

void WtfGraphics::Draw2DLine(const iVector2D& a, const iVector2D& b, int iWidth) {
	iVector2D vDelta = b - a;
	fVector3D v = fVector3D(-vDelta[1], vDelta[0], 0.0) * (0.5 * float(iWidth) / vDelta.length());
	fVector3D va(a[0], a[1], 0), vb(b[0], b[1], 0);

	glBegin(GL_QUADS);

	glVertex3fv((va + v).toArray());
	glVertex3fv((va - v).toArray());
	glVertex3fv((vb - v).toArray());
	glVertex3fv((vb + v).toArray());

	glEnd();
};

void WtfGraphics::SaveProjection() {
	glPushAttrib(GL_VIEWPORT_BIT);
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glMatrixMode(GL_MODELVIEW);
	WtfGraphics::SaveView();
};

void WtfGraphics::RestoreProjection() {
	WtfGraphics::RestoreView();
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glPopAttrib();

	glMatrixMode(GL_MODELVIEW);
};

void WtfGraphics::SetupOrthoProjection(const WtfEngine::IScreen::tRef& rScreen) {
	tScalar x, y;

	x = rScreen->getSize().x();
	y = rScreen->getSize().y();

	
	glViewport(0,0,x,y);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0, x, 0, y);
	checkGLError("setting ortho");

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
};

void WtfGraphics::ClearScreen() {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
};
